﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace SimpleDatabaseAdapter
{
    internal class AllDataColumns
    {
        internal static readonly string[] COLUMN_NO_USE_IN_INSERT = new string[] { COLUMN_ID };
        internal static readonly string[] COLUMN_NO_USE_IN_UPDATE = new string[] { COLUMN_ID, COLUMN_CREATE_DATA, COLUMN_LIST_ID };

        internal const string COLUMN_ID = "Id";
        internal const string COLUMN_CREATE_DATA = "CreateDate";
        internal const string COLUMN_MODIFY_DATA = "ModifyDate";
        internal const string COLUMN_LIST_ID = "ListId";

        internal const int columnNvarchar255Count = 20;
        internal const int columnNvarcharMAXCount = 10;
        internal const int columnNvarcharIntCount = 10;
        internal const int columnNvarcharFloatCount = 10;
        internal const int columnNvarcharBitCount = 10;
        internal const int columnNvarcharDatetimeCount = 10;

        internal const string columnNvarchar255Name = "nvarchar255";
        internal const string columnNvarcharMAXName = "nvarcharMAX";
        internal const string columnNvarcharIntName = "int";
        internal const string columnNvarcharFloatName = "float";
        internal const string columnNvarcharBitName = "bit";
        internal const string columnNvarcharDatetimeName = "datetime";

        internal static string GetAllDataColumnName(List<ListColumnBase> allColumns, ListColumnBase newColumn)
        {
            string startColumnName = String.Empty;
            int columnsCount = 0;

            if (newColumn.Type == AllDataColumnTypes.String)
            {
                startColumnName = columnNvarchar255Name;
                columnsCount = columnNvarchar255Count;
            }
            if (newColumn.Type == AllDataColumnTypes.Text)
            {
                startColumnName = columnNvarcharMAXName;
                columnsCount = columnNvarcharMAXCount;
            }
            if (newColumn.Type == AllDataColumnTypes.Int)
            {
                startColumnName = columnNvarcharIntName;
                columnsCount = columnNvarcharIntCount;
            }
            if (newColumn.Type == AllDataColumnTypes.Float)
            {
                startColumnName = columnNvarcharFloatName;
                columnsCount = columnNvarcharFloatCount;
            }
            if (newColumn.Type == AllDataColumnTypes.Bool)
            {
                startColumnName = columnNvarcharBitName;
                columnsCount = columnNvarcharBitCount;
            }
            if (newColumn.Type == AllDataColumnTypes.DateTime)
            {
                startColumnName = columnNvarcharDatetimeName;
                columnsCount = columnNvarcharDatetimeCount;
            }

            int newColumnIndex = GetNewColumnIndex(allColumns, newColumn, startColumnName, columnsCount);
            string allColumnName = string.Format("{0}_{1}", startColumnName, newColumnIndex);
            return allColumnName;
        }

        private static int GetNewColumnIndex(List<ListColumnBase> allColumns, ListColumnBase newColumn, string startColumnName, int columnsCount)
        {
            bool[] columnsSet = new bool[columnsCount];
            int index;

            foreach (ListColumnBase column in allColumns)
            {
                if (column.Type == newColumn.Type)
                {
                    index = GetColumnIndex(column.AllDataColumnName, startColumnName);
                    columnsSet[index] = true;
                }
            }

            for (int i = 0; i < columnsCount; i++)
            {
                if (columnsSet[i] == false)
                {
                    return i;
                }
            }

            throw new Exception(string.Format("Not have columns for type '{0}'.", newColumn.Type));
        }
        private static int GetColumnIndex(string columnName, string startColumnName)
        {
            string columnIndexStr = columnName.Replace(startColumnName, String.Empty).Replace("_", String.Empty);
            
            int index = -1;
            
            if (!int.TryParse(columnIndexStr, out index))
            {
                throw new Exception(string.Format("Column name '{0}' is bad", columnName));
            }
            
            return index;
        }

        internal static bool IsSystemColumn(string columnName)
        {
            string[] systemColumns = GetSystemColumns();
            bool isSystem = systemColumns.Contains(columnName);
            return isSystem;
        }
        private static string[] GetSystemColumns()
        {
            if (_SystemColumns == null)
            {
                _SystemColumns = Propertyes.GetAllDataItemAttributes(typeof(AllDataItemBase)).Select(x => x.StaticName).ToArray();
            }
            return _SystemColumns;
        }
        private static string[] _SystemColumns;
    }

    public enum AllDataColumnTypes
    {
        String, Text, Int, Float, Bool, DateTime
    }

}
